package com.only4play.practice.common.utils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author mengdy
 */
public class DateFormatUtils {
    // 以毫秒表示的时间
    private static final long DAY_IN_MILLIS = 24 * 3600 * 1000;
    private static final long HOUR_IN_MILLIS = 3600 * 1000;
    private static final long MINUTE_IN_MILLIS = 60 * 1000;
    private static final long SECOND_IN_MILLIS = 1000L;
    public static final String PATTERN_CLASSICAL = "yyyy-MM-dd HH:mm:ss";
    public static final String PATTERN_CLASSICAL_NORMAL = "yyyy-MM-dd HH:mm";
    public static final String PATTERN_CLASSICAL_SIMPLE = "yyyy-MM-dd";
    public static final String PATTERN_CLASSICAL_YMD = "yyyyMMdd";
    public static final String PATTERN_CLASSICAL_yyyy_MM_dd_HH_mm = "yyyy-MM-dd-HH-mm";
    public static final String PATTERN_CLASSICAL_yyyyMMddHHmm = "yyyyMMddHHmm";
    public static final String PATTERN_CLASSICAL_HM = "HH:mm";
    public static final String PATTERN_CH = "yyyy年MM月dd日 HH时mm分ss秒";
    public static final String PATTERN_CH_NORMAL = "yyyy年MM月dd日 HH时mm分";
    public static final String PATTERN_CH_SIMPLE = "yyyy年MM月dd日";

    public DateFormatUtils() {
    }

    /*=====================================Date转化为指定格式的日期String===================================*/


    /**
     * Date转化为指定格式的日期String,默认格式为yyyy-MM-dd HH:mm:ss
     */
    public static String format(Date date) {
        return format(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 指定 pattern 格式
     */
    public static String format(Date date, String pattern) {
        if (date == null) {
            return null;
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            return sdf.format(date);
        }
    }

    /*=====================================指定格式的日期String解析为Date===================================*/

    /**
     * 指定格式的日期String解析为Date, 默认格式为yyyy-MM-dd HH:mm:ss
     */
    public static Date parse(String str) {
        return parse(str, "yyyy-MM-dd HH:mm:ss");
    }

    public static Date parse(String str, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);

        try {
            return sdf.parse(str);
        } catch (ParseException var4) {
            throw new RuntimeException(var4.getMessage());
        }
    }


    /**
     * 指定格式的日期String转化为Calendar日历对象
     */
    public static Calendar parseCalendar(String src, String pattern) {
        Date date = parse(src, pattern);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal;
    }
    /**
     * 指定格式的日期String转化为Timestamp对象
     */
    public static Timestamp parseTimestamp(String src, String pattern) {
        Date date = parse(src, pattern);
        return new Timestamp(date.getTime());
    }

    /**
     * 通过日历Calendar实现Date日期对象天数的加减操作
     * @param date 要进行加减操作的日期对象
     * @param dayNums 要进行加减的天数, 正数为加, 负数为减
     */
    public static Date addDaysByCalendar(Date date, int dayNums) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, dayNums);
        return calendar.getTime();
    }

    public static Date addHoursByCalendar(Date date, int hourNums) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, hourNums);
        return calendar.getTime();
    }

    public static Date addMinutesByCalendar(Date date, int minuteNums) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minuteNums);
        return calendar.getTime();
    }

    public static Date addSecondsByCalendar(Date date, int secondNums) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, secondNums);
        return calendar.getTime();
    }

    // 加减月操作
    public static Date addMonthsByCalendar(Date date, int monthNums) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, monthNums);
        return calendar.getTime();
    }

    public static Date addYearsByCalendar(Date date, int yearNums) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, yearNums);
        return calendar.getTime();
    }

    /**
     * 计算两个Date对象之间的差值
     * @param type 差值类型
     * @param minuendDate 减方
     * @param dateSub 减数
     * @return 插值
     */
    public static int dateDiff(char type, Date minuendDate, Date dateSub) {
        Calendar calDes = Calendar.getInstance();
        Calendar calStr = Calendar.getInstance();
        if (null == minuendDate) {
            minuendDate = new Date();
        }

        calStr.setTime(minuendDate);
        calDes.setTime(dateSub);
        return dateDiff(type, calStr, calDes);
    }

    /**
     * 计算两个Calendar对象之间的差值
     * @param flag 类型
     * @param calSrc 减方
     * @param calDes 被减方
     * @return 差值
     */
    public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) {
        //
        long millisDiff = calSrc.getTime().getTime() - calDes.getTime().getTime();

        if (flag == 'y') {
            return calSrc.get(Calendar.YEAR) - calDes.get(Calendar.YEAR);
        } else if (flag == 'M') {
            return calSrc.get(Calendar.MONTH) + (calSrc.get(Calendar.YEAR) - calDes.get(Calendar.YEAR)) * 12 - calDes.get(Calendar.MONTH);
        } else if (flag == 'd') {
            return (int)(millisDiff / 86400000L);
        } else if (flag == 'h') {
            return (int)(millisDiff / 3600000L);
        } else if (flag == 'm') {
            return (int)(millisDiff / 60000L);
        } else {
            return flag == 's' ? (int)(millisDiff / 1000L) : 0;
        }
    }



    public static int getDayFromDate(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        return ca.get(Calendar.DATE);
    }

    public static int getMonthFromDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    public static String getWeekdayDescFromDate(Date date) {
        String[] weeks = new String[]{"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        if (date != null) {
            cal.setTime(date);
        }
        return weeks[cal.get(Calendar.DAY_OF_WEEK) - 1];
    }

    /**
     * 返回指定Date日期对应的起始时间，如果是2012-01-01 13:05:06，则返回2012-01-01 00:00:00
     */
    public static Date getStartTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 返回指定Date日期对应的结束时间，比如2012-01-01 13:05:06，则返回2012-01-01 23:59:59
     */
    public static Date getEndTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     *  判断两个Date对象是否是同一天
     */
    public static boolean isSameDay(Date date1, Date date2) {
        return format(date1, PATTERN_CLASSICAL_SIMPLE).equals(format(date2, PATTERN_CLASSICAL_SIMPLE));
    }
}